using System;
using System.Collections.Generic;
using System.Linq;

// 定义成绩打印委托类型
public delegate bool GradePrint(Student s);

// 学生类
public class Student
{
    // 属性
    public string Name { get; set; }
    public int StudentId { get; set; }
    public Dictionary<string, double> Grades { get; set; } // 科目名称和成绩的字典
    public double AverageGrade { get; set; } // 平均成绩
    
    // 委托属性
    public GradePrint GP { get; set; }

    // 构造函数
    public Student(string name, int studentId)
    {
        Name = name;
        StudentId = studentId;
        Grades = new Dictionary<string, double>();
        AverageGrade = 0;
    }

    // 添加成绩
    public void AddGrade(string subject, double score)
    {
        if (Grades.ContainsKey(subject))
        {
            Grades[subject] = score;
        }
        else
        {
            Grades.Add(subject, score);
        }
        // 更新平均成绩
        UpdateAverageGrade();
    }

    // 更新平均成绩
    private void UpdateAverageGrade()
    {
        if (Grades.Count > 0)
        {
            AverageGrade = Grades.Values.Average();
        }
        else
        {
            AverageGrade = 0;
        }
    }

    // 打印成绩（使用委托）
    public bool PrintGrade()
    {
        if (GP != null)
        {
            return GP(this);
        }
        else
        {
            Console.WriteLine("未设置成绩打印委托");
            return false;
        }
    }
}

// 成绩单类
public class GradeReport
{
    // 按学期排序打印成绩
    public static bool OrderByTerm(Student s)
    {
        Console.WriteLine($"=== {s.Name} (学号: {s.StudentId}) 的成绩单 - 按学期排序 ===");
        Console.WriteLine($"平均成绩: {s.AverageGrade:F2}");
        Console.WriteLine("成绩详情:");
        
        // 这里假设科目名称中包含学期信息，简单按科目名称排序
        foreach (var grade in s.Grades.OrderBy(g => g.Key))
        {
            Console.WriteLine($"{grade.Key}: {grade.Value:F2}");
        }
        Console.WriteLine("==============================================\n");
        return true;
    }

    // 按成绩高低排序打印
    public static bool OrderByScore(Student s)
    {
        Console.WriteLine($"=== {s.Name} (学号: {s.StudentId}) 的成绩单 - 按成绩排序 ===");
        Console.WriteLine($"平均成绩: {s.AverageGrade:F2}");
        Console.WriteLine("成绩详情 (从高到低):");
        
        foreach (var grade in s.Grades.OrderByDescending(g => g.Value))
        {
            Console.WriteLine($"{grade.Key}: {grade.Value:F2}");
        }
        Console.WriteLine("==============================================\n");
        return true;
    }

    // 只打印及格成绩
    public static bool PrintPassingGrades(Student s)
    {
        Console.WriteLine($"=== {s.Name} (学号: {s.StudentId}) 的及格成绩单 ===");
        var passingGrades = s.Grades.Where(g => g.Value >= 60).ToList();
        
        if (passingGrades.Count > 0)
        {
            Console.WriteLine($"及格科目数量: {passingGrades.Count}");
            Console.WriteLine("及格成绩详情:");
            foreach (var grade in passingGrades.OrderBy(g => g.Key))
            {
                Console.WriteLine($"{grade.Key}: {grade.Value:F2}");
            }
        }
        else
        {
            Console.WriteLine("无及格科目");
        }
        Console.WriteLine("==============================================\n");
        return passingGrades.Count > 0;
    }

    // 打印成绩分析报告
    public static bool PrintDetailedAnalysis(Student s)
    {
        Console.WriteLine($"=== {s.Name} (学号: {s.StudentId}) 的成绩分析报告 ===");
        Console.WriteLine($"总科目数: {s.Grades.Count}");
        Console.WriteLine($"平均成绩: {s.AverageGrade:F2}");
        Console.WriteLine($"最高成绩: {s.Grades.Values.Max():F2} ({s.Grades.First(g => g.Value == s.Grades.Values.Max()).Key})");
        Console.WriteLine($"最低成绩: {s.Grades.Values.Min():F2} ({s.Grades.First(g => g.Value == s.Grades.Values.Min()).Key})");
        Console.WriteLine($"及格科目数: {s.Grades.Count(g => g.Value >= 60)}");
        Console.WriteLine($"优秀科目数 (≥85): {s.Grades.Count(g => g.Value >= 85)}");
        Console.WriteLine($"不及格科目数: {s.Grades.Count(g => g.Value < 60)}");
        
        // 按科目分类统计
        Console.WriteLine("\n成绩分布:");
        int excellent = s.Grades.Count(g => g.Value >= 85);
        int good = s.Grades.Count(g => g.Value >= 70 && g.Value < 85);
        int pass = s.Grades.Count(g => g.Value >= 60 && g.Value < 70);
        int fail = s.Grades.Count(g => g.Value < 60);
        
        Console.WriteLine($"优秀 (85-100): {excellent} 门");
        Console.WriteLine($"良好 (70-84): {good} 门");
        Console.WriteLine($"及格 (60-69): {pass} 门");
        Console.WriteLine($"不及格 (0-59): {fail} 门");
        Console.WriteLine("==============================================\n");
        return true;
    }
}

// 主程序类
class Program
{
    static void Main(string[] args)
    {
        // 创建学生对象
        Student student1 = new Student("张三", 1001);
        student1.AddGrade("高等数学", 85.5);
        student1.AddGrade("程序设计", 92.0);
        student1.AddGrade("大学英语", 78.5);
        student1.AddGrade("数据结构", 95.0);
        student1.AddGrade("操作系统", 76.0);

        Student student2 = new Student("李四", 1002);
        student2.AddGrade("高等数学", 65.5);
        student2.AddGrade("程序设计", 88.0);
        student2.AddGrade("大学英语", 59.0);
        student2.AddGrade("数据结构", 91.5);
        student2.AddGrade("操作系统", 82.0);

        // 演示不同的打印模板
        Console.WriteLine("===== 测试不同的成绩打印模板 =====\n");

        // 1. 使用按学期排序的模板
        Console.WriteLine("1. 设置学生1使用按学期排序的打印模板:");
        student1.GP = GradeReport.OrderByTerm;
        student1.PrintGrade();

        // 2. 使用按成绩排序的模板
        Console.WriteLine("2. 切换学生1使用按成绩排序的打印模板:");
        student1.GP = GradeReport.OrderByScore;
        student1.PrintGrade();

        // 3. 使用只打印及格成绩的模板
        Console.WriteLine("3. 设置学生2使用只打印及格成绩的模板:");
        student2.GP = GradeReport.PrintPassingGrades;
        student2.PrintGrade();

        // 4. 使用详细分析报告模板
        Console.WriteLine("4. 切换学生2使用详细分析报告模板:");
        student2.GP = GradeReport.PrintDetailedAnalysis;
        student2.PrintGrade();

        // 5. 使用自定义的匿名方法作为模板
        Console.WriteLine("5. 使用自定义匿名方法作为打印模板:");
        student1.GP = delegate(Student s) 
        {
            Console.WriteLine($"=== {s.Name} 的自定义成绩单 ===");
            Console.WriteLine($"学号: {s.StudentId}");
            Console.WriteLine("主要科目成绩:");
            foreach (var grade in s.Grades)
            {
                if (grade.Value >= 80)
                {
                    Console.WriteLine($"{grade.Key}: {grade.Value:F2} (优秀)");
                }
                else if (grade.Value >= 60)
                {
                    Console.WriteLine($"{grade.Key}: {grade.Value:F2} (及格)");
                }
                else
                {
                    Console.WriteLine($"{grade.Key}: {grade.Value:F2} (需要努力)");
                }
            }
            Console.WriteLine("==============================================\n");
            return true;
        };
        student1.PrintGrade();

        // 6. 使用Lambda表达式作为模板
        Console.WriteLine("6. 使用Lambda表达式作为打印模板:");
        student2.GP = s => 
        {
            Console.WriteLine($"=== {s.Name} 的Lambda成绩单 ===");
            Console.WriteLine($"平均分为 {(s.AverageGrade >= 80 ? "优秀" : s.AverageGrade >= 60 ? "及格" : "不及格")}");
            Console.WriteLine($"共有 {s.Grades.Count} 门课程");
            Console.WriteLine("==============================================\n");
            return true;
        };
        student2.PrintGrade();

        // 保持控制台窗口打开
        Console.WriteLine("按任意键退出...");
        Console.ReadKey();
    }
}